﻿using IDEAMS.core.opm;
using IDEAMS.core.queue;
using IDEAMS.model;
using IDEAMS.model.device;
using IDEAMS.utils;
using log4net;
using System;
using System.Threading;

namespace IDEAMS.core.deviceClient
{
    public class DeviceDataWorker
    {
        private static ILog logger = LogManager.GetLogger(typeof(DeviceDataWorker));

        private readonly object locker = new object();

        public OPM_MsgDispatcher msgDispatcher = new OPM_MsgDispatcher();
        public OPM_Connector opm_Connector;
        private ConnectionStatus status;
        private Thread thWorker = null;
        private bool stopFlag = true;

        public bool isWaveStart = false;

        public string ip { get; set; }
        public int port { get; set; }

        public string serialNo { get; set; }

        // 光谱Summary数据
        SpectrumSummaryResp srcSsResp = new SpectrumSummaryResp();
        public SpectrumSummaryResp ssResp = new SpectrumSummaryResp();
        public int sampleQuantity = 1;

        public void ResetSpectrumSummary()
        {
            ssResp = new SpectrumSummaryResp(srcSsResp, sampleQuantity);
        }


        public DeviceDataWorker()
        {
            opm_Connector = new OPM_Connector();
            status = ConnectionStatus.OFFLINE;
            TW_App.delegateCollection.SyncConnectionStatusChange(serialNo, status);
        }

        public DeviceDataWorker(string ip, int port) : this()
        {
            this.ip = ip;
            this.port = port;
        }

        public int Connect(Action<DeviceParam,int> action)
        {
            return Connect(ip, port, 1000, ref action);
        }

        public int Connect(string ip, int port, int milliseconds, ref Action<DeviceParam,int> action)
        {
            int rn = 0;

            lock(locker)
            {
                try
                {
                    rn = opm_Connector.Init(ip, port);
                    if (rn != 0)
                    {
                        if(status != ConnectionStatus.OFFLINE)
                        {
                            this.status = ConnectionStatus.OFFLINE;
                        }
                        string errMsg = string.Format("设备连接器初始化失败，ip={0}, port={1}", ip, port);
                        throw new Exception(errMsg);
                    }

                    opm_Connector.SetRecvTimeOut(1000);
                    rn = OPMStop();
                    if (rn != 0)
                    {
                        if (status != ConnectionStatus.OFFLINE)
                        {
                            this.status = ConnectionStatus.OFFLINE;
                        }
                        string errMsg = string.Format("设备连接失败，ip={0}, port={1}", ip, port);
                        throw new Exception(errMsg);
                    }
                    isWaveStart = false;

                    this.status = ConnectionStatus.CONNECTED;

                    opm_Connector.SetRecvTimeOut(milliseconds);

                    DeviceParam deviceParam = ReadDeviceParam();
                    if(deviceParam== null)
                    {
                        string errMsg = string.Format("设备客户端读取设备参数失败,ip={0}, port={1}", ip, port);
                        DisConnect();
                        logger.InfoFormat("设备客户端命令端口断开连接,ip={0}, port={1}", ip, port);
                        Thread.Sleep(1000);
                        throw new Exception(errMsg);
                    }

                    serialNo = deviceParam.serialNo;
                    TW_App.delegateCollection.SyncConnectionStatusChange(serialNo, status);

                    // 读取刷新频率
                    int frequency = ReadCurrentFrequency();
                    if (frequency == -1)
                    {
                        string errMsg = string.Format("设备客户端读取当前频率失败,ip={0}, port={1}", ip, port);
                        DisConnect();
                        logger.InfoFormat("设备客户端命令端口断开连接,ip={0}, port={1}", ip, port);
                        Thread.Sleep(1000);
                        throw new Exception(errMsg);
                    }

                    GetSpectrumSummary();

                    if(action != null)
                    {
                        action(deviceParam,frequency);
                    }

                    logger.InfoFormat("设备客户端命令端口连接成功,ip={0}, port={1}", ip, port);

                }
                catch(Exception)
                {
                    if (status != ConnectionStatus.OFFLINE)
                    {
                        this.status = ConnectionStatus.OFFLINE;
                    }
                    Thread.Sleep(1000);
                }
            }

            return rn;
        }

        public int DisConnect()
        {
            opm_Connector.End();
            status = ConnectionStatus.OFFLINE;
            TW_App.delegateCollection.SyncConnectionStatusChange(serialNo, status);
            return 0;
        }

        public ConnectionStatus GetStatus()
        {
            lock (locker)
            {
                return status;
            }
        }

        public int StartReceiveSync(Action<DeviceParam,int> action)
        {
            int rn = 0;

            // 停止时才能启动，如果已启动不重复启动
            if (stopFlag)
            {
                thWorker = new Thread(new ThreadStart(() => StartReceive(action)));
                if(thWorker != null)
                {
                    thWorker.Start();
                }
                else
                {
                    rn = -1;
                }
            }
            return rn;
        }

        public void StartReceive(Action<DeviceParam,int> action)
        {
            stopFlag = false;
            int msgLen = 0;
            int rn = 0;

            if(status == ConnectionStatus.CONNECTED)
            {
                opm_Connector.SetRecvTimeOut(3000);
            }

            logger.DebugFormat("设备客户端数据接收线程启动");
            while(!stopFlag)
            {
                try
                {
                    if (status == ConnectionStatus.OFFLINE)
                    {
                        rn = Connect(ip, port, 3000, ref action);
                        if (rn != 0)
                        {
                            logger.ErrorFormat("设备客户端数据接收连接失败,ip={0}, port={1}", ip, port);
                            continue;
                        }
                        else
                        {
                            logger.InfoFormat("设备数据端口连接成功,ip={0}, port={1}", ip, port);
                        }
                    }
                    else
                    {
                        if (isWaveStart)
                        {
                            byte[] buff = new byte[4096];

                            msgLen = opm_Connector.RecvMsg(ref buff, 0);
                            if (msgLen < 0)
                            {
                                logger.ErrorFormat("连接已经断开，ip={0}, port={1}", ip, port);
                                DisConnect();
                                continue;
                            }
                            QueueData data = null;
                            OPM_CmdID cmdID = OPM_Protocol.GetCmd(buff, buff.Length);
                            switch (cmdID)
                            {
                                case OPM_CmdID.CMD_READ_GRATING_WAVE_LEN:
                                    Wave waveLen = new Wave();
                                    waveLen.serialNo = this.serialNo;
                                    waveLen.type = QueueDataType.DATA_WL;
                                    OPM_Protocol.ParseWaveLenPackage(buff, msgLen, ref waveLen);
                                    data = waveLen;
                                    break;
                                case OPM_CmdID.CMD_READ_GRATING_WAVE_LEN_G:
                                    Wave waveLen_g = new Wave();
                                    waveLen_g.serialNo = this.serialNo;
                                    waveLen_g.type = QueueDataType.DATA_WL;
                                    OPM_Protocol.ParseWaveLenGPackage(buff, msgLen, ref waveLen_g);
                                    data = waveLen_g;
                                    break;
                                case OPM_CmdID.CMD_READ_GRATING_WAVE_LEN_DB:
                                    Wave waveLen_db = new Wave();
                                    waveLen_db.serialNo = this.serialNo;
                                    waveLen_db.type = QueueDataType.DATA_WL;
                                    OPM_Protocol.ParseWaveLenDBPackage(buff, msgLen, ref waveLen_db);
                                    data = waveLen_db;
                                    break;
                                case OPM_CmdID.CMD_START_FLAG:
                                    StartControl control = new StartControl();
                                    OPM_Protocol.ParseStartPackage(buff, msgLen, ref control);
                                    //if (control.startFlag == 0x55)
                                    //{
                                    //    // 启动
                                    //    isWaveStart = true;
                                    //}
                                    //else
                                    //{
                                    //    isWaveStart = false;
                                    //}
                                    break;
                                case OPM_CmdID.CMD_READ_SPECTRUM_SUMMARY:
                                    srcSsResp = new SpectrumSummaryResp();
                                    OPM_Protocol.ParseSpectrumSummaryRespPackage(buff, ref srcSsResp);
                                    ssResp = new SpectrumSummaryResp(srcSsResp, sampleQuantity);
                                    //TW_App.delegateCollection.SyncReadSpectrumSummaryResp(srcSsResp);
                                    break;
                                case OPM_CmdID.CMD_READ_SPECTRUM:
                                    int pkgNo = buff[3]; // 第几帧
                                    if (pkgNo == ssResp.frameNum - 1)
                                    {
                                        break;
                                    }
                                    SpectrumZData spData = new SpectrumZData();
                                    int DataCountsPerPkg = (msgLen - 4) / 2;
                                    int dataCounts = (ssResp.dataNum - pkgNo * DataCountsPerPkg) > DataCountsPerPkg ? DataCountsPerPkg : (ssResp.dataNum - pkgNo * DataCountsPerPkg);
                                    if (-1 != OPM_Protocol.ParseSpectrumZDataPackage(buff, dataCounts, ssResp, ref spData))
                                    {
                                        spData.type = QueueDataType.DATA_SP;
                                        data = spData;
                                    }
                                    break;
                                case OPM_CmdID.CMD_READ_CHANNEL_PARAMETER:
                                    ReadChannelParameterResp rcpResp = new ReadChannelParameterResp();
                                    OPM_Protocol.ParseReadChannelParameterRespPackage(buff, ref rcpResp);
                                    rcpResp.serialNo = serialNo;
                                    TW_App.delegateCollection.SyncReadChParameter(rcpResp);
                                    break;
                                case OPM_CmdID.CMD_SET_CHANNEL_PARAMETER:
                                    TW_App.delegateCollection.SyncSettingChParameter();
                                    break;
                                default:
                                    logger.ErrorFormat("unknown message type({0})", cmdID);
                                    break;
                            }

                            msgDispatcher.NotifyAll(data);
                        }
                        else
                        {
                            rn = OPMStop();
                            if (rn != 0)
                            {
                                if (status != ConnectionStatus.OFFLINE)
                                {
                                    status = ConnectionStatus.OFFLINE;
                                    TW_App.delegateCollection.SyncConnectionStatusChange(serialNo, status);
                                }
                            }
                            Thread.Sleep(1000);
                        }
                    }
               
                }
                catch (Exception ex)
                {
                    Console.WriteLine("数据接收报错:"+ex.Message);
                    logger.ErrorFormat("数据接收报错:{0}", ex.Message);
                }
            }
            logger.DebugFormat("设备客户端数据接收线程退出");
        }

        public void StopReceive()
        {
            stopFlag = true;
        }

        public bool IsStop()
        {
            return stopFlag;
        }

        /// <summary>
        /// 等待线程正常结束
        /// </summary>
        public void Join()
        {
            try
            {
                if (thWorker != null)
                {
                    thWorker.Join();
                }
            }
            catch (Exception)
            {
                string errMsg = string.Format("worker {0} Join操作异常", thWorker.ManagedThreadId);
                logger.ErrorFormat(errMsg);
            }
        }

        /// <summary>
        /// 等待线程结束
        /// (超时退出)
        /// </summary>
        public bool Join(int milliSeconds)
        {
            bool flag = true;
            if (thWorker != null)
            {
                try
                {
                    flag = thWorker.Join(milliSeconds);
                }
                catch (Exception)
                {
                    string errMsg = string.Format("device data receiver {0} Join操作异常", thWorker.ManagedThreadId);
                    logger.ErrorFormat(errMsg);
                }
            }

            return flag;
        }

        #region 波长启动与停止
        /// <summary>
        /// 启动波长数据发送
        /// </summary>
        /// <returns></returns>
        public int OPMStart()
        {
            byte[] buffer = new byte[4];
            StartControl startControl = new StartControl();
            startControl.head.cmd1 = 0x01;
            startControl.head.cmd2 = 0x0a;
            startControl.startFlag = StartControl.START;
            int length = OPM_Protocol.MakeStartPackage(ref buffer, startControl);

            int rn = opm_Connector.SendToServer(buffer, 0, length);
            if (rn != length)
            {
                return -1;
            }

            //RECV 应答
            byte[] startRespBuffer = new byte[4096];
            int msgLen = opm_Connector.RecvMsg(ref startRespBuffer, 0);
            if (msgLen < 0)
            {
                return -1;
            }

            OPM_CmdID cmd_id = OPM_Protocol.GetCmd(startRespBuffer, msgLen);
            if (cmd_id != OPM_CmdID.CMD_START_FLAG) //不是启动命令
            {
                return -1;
            }

            StartControl sc = new StartControl();
            rn = OPM_Protocol.ParseStartPackage(startRespBuffer, msgLen, ref sc);
            if (sc.startFlag != StartControl.START) //不是启动标志
            {
                return -1;
            }
            return 0;
        }

        /// <summary>
        /// 停止波长数据发送
        /// </summary>
        /// <returns></returns>
        public int OPMStop()
        {
            lock (locker)
            {
                byte[] stopBuffer = new byte[4];
                StartControl control = new StartControl();
                control.head.cmd1 = 0x01;
                control.head.cmd2 = 0x0a;
                control.startFlag = StartControl.STOP;
                int length = OPM_Protocol.MakeStartPackage(ref stopBuffer, control);

                int rn = opm_Connector.SendToServer(stopBuffer, 0, length);
                if (rn != length)
                {
                    return -1;
                }


                // RECV 应答
                byte[] stopRespBuffer = new byte[4096];
                int msgLen = opm_Connector.RecvMsg(ref stopRespBuffer, 0);
                if (msgLen < 0)
                {
                    return -1;
                }

                OPM_CmdID cmd_id = OPM_Protocol.GetCmd(stopRespBuffer, msgLen);
                if (cmd_id != OPM_CmdID.CMD_START_FLAG) //不是启动命令
                {
                    return -1;
                }

                StartControl sc = new StartControl();
                rn = OPM_Protocol.ParseStartPackage(stopRespBuffer, msgLen, ref sc);
                if (sc.startFlag != StartControl.STOP) //不是启动标志
                {
                    return -1;
                }
            }
            
            return 0;
        }

        public void OPMStop_SendOnly()
        {
            byte[] stopBuffer = new byte[4];
            StartControl control = new StartControl();
            control.head.cmd1 = 0x01;
            control.head.cmd2 = 0x0a;
            control.startFlag = StartControl.STOP;
            int length = OPM_Protocol.MakeStartPackage(ref stopBuffer, control);

            opm_Connector.SendToServer(stopBuffer, 0, length);
        }

        #endregion

        #region 读取设备参数
        public DeviceParam ReadDeviceParam()
        {
            DeviceParam deviceParam = new DeviceParam();

            if(status != ConnectionStatus.CONNECTED)
            {
                logger.ErrorFormat("读取设备参数命令执行失败,因为设备还未连接成功, ip={0}, port={1}", ip, port);
                return null;
            }

            lock(locker)
            {
                byte[] buffer = new byte[1024];
                byte[] respBuffer = new byte[4096];
                int rn;


                // 读取设备参数
                ReadDeviceBaseInfoReq deviceBaseInfoReq = new ReadDeviceBaseInfoReq();
                deviceBaseInfoReq.head.cmd1 = 0x01;
                deviceBaseInfoReq.head.cmd2 = (byte)OPM_CmdID.CMD_READ_PARAMETER;
                int length = OPM_Protocol.MakeReadDeviceBaseInfoReqPackage(ref buffer, deviceBaseInfoReq);
                rn = opm_Connector.SendToServer(buffer, 0, length);
                if (rn != length)
                {
                    return null;
                }

                // 接收和解析设备信息应答消息
                int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                if (msgLen < 0)
                {
                    return null;
                }
                OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                if (cmd_id != OPM_CmdID.CMD_READ_PARAMETER)
                {
                    return null;
                }
                ReadDeviceBaseInfoResp dbiResp = new ReadDeviceBaseInfoResp();
                rn = OPM_Protocol.ParseReadDeviceBaseInfoRespPackage(respBuffer, ref dbiResp);
                if (rn != 0)
                {
                    return null;
                }

                deviceParam.FormResp(dbiResp);
            }

            return deviceParam;
        }

        #endregion

        #region 光谱相关
        /// <summary>
        /// 发送获取光谱summary命令
        /// </summary>
        /// <returns></returns>
        public int GetSpectrumSummary()
        {
            if(status != ConnectionStatus.CONNECTED)
            {
                return -1;
            }

            lock(locker)
            {
                // 发送光谱summary请求消息
                byte[] buffer = new byte[1024];
                SpectrumSummaryReq ssReq = new SpectrumSummaryReq();
                ssReq.head.cmd1 = 0x01;
                ssReq.head.cmd2 = (byte)OPM_CmdID.CMD_READ_SPECTRUM_SUMMARY;

                int length = OPM_Protocol.MakeSpectrumSummaryReqPackage(ref buffer, ssReq);

                int rn = opm_Connector.SendToServer(buffer, 0, length);
                if (rn != length)
                {
                    return -1;
                }

                if(!isWaveStart)
                {
                    // 接收和解析设备信息应答消息
                    byte[] respBuffer = new byte[1024];
                    int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                    if (msgLen < 0)
                    {
                        return -1;
                    }
                    OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                    if (cmd_id != OPM_CmdID.CMD_READ_SPECTRUM_SUMMARY)
                    {
                        return -1;
                    }
                    rn = OPM_Protocol.ParseSpectrumSummaryRespPackage(respBuffer, ref srcSsResp);
                    if (rn != 0)
                    {
                        return -1;
                    }

                    ResetSpectrumSummary();
                }
            }
            
            return 0;
        }


        public int ReadSpectrum(ChannelItemViewModel channel)
        {
            if (opm_Connector != null && opm_Connector.GetStatus() == 0)
            {
                if (ssResp == null || ssResp.channelNum == 0)
                {
                    GetSpectrumSummary();
                    return -1;

                }

                if(channel.no > ssResp.channelNum)
                {
                    return -1;
                }
                lock (locker)
                {
                    if(channel.no == 0)
                    {
                        for(int k = 0; k< ssResp.channelNum;k++)
                        {
                            int length = 0;
                            byte[] buffer = new byte[1024];
                            // 发送光谱请求消息
                            SpectrumReq specReq = new SpectrumReq();
                            specReq.head.cmd1 = 0x01;
                            specReq.head.cmd2 = (byte)OPM_CmdID.CMD_READ_SPECTRUM;
                            specReq.chID = k;
                            specReq.sampleQuantity = sampleQuantity;
                            length = OPM_Protocol.MakeSpectrumReqPackage(ref buffer, specReq);
                            int rn = opm_Connector.SendToServer(buffer, 0, length);
                            if (rn != length)
                            {
                                return -1;
                            }

                            if (!isWaveStart)
                            {
                                QueueData data = null;
                                for (int i = 0; i < ssResp.frameNum; i++)
                                {
                                    // 接收和解析设备信息应答消息
                                    byte[] respBuffer = new byte[1024];
                                    int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                                    if (msgLen < 0)
                                    {
                                        return -1;
                                    }
                                    OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                                    if (cmd_id != OPM_CmdID.CMD_READ_SPECTRUM)
                                    {
                                        return -1;
                                    }

                                    int pkgNo = respBuffer[3]; // 第几帧
                                    if (pkgNo == ssResp.frameNum - 1)
                                    {
                                        break;
                                    }
                                    SpectrumZData spData = new SpectrumZData();
                                    int DataCountsPerPkg = (msgLen - 4) / 2;
                                    int dataCounts = (ssResp.dataNum - pkgNo * DataCountsPerPkg) > DataCountsPerPkg ? DataCountsPerPkg : (ssResp.dataNum - pkgNo * DataCountsPerPkg);
                                    if (-1 != OPM_Protocol.ParseSpectrumZDataPackage(respBuffer, dataCounts, ssResp, ref spData))
                                    {
                                        spData.type = QueueDataType.DATA_SP;
                                        data = spData;
                                    }

                                    msgDispatcher.NotifyAll(data);
                                }
                            }
                        }
                    }
                    else
                    {
                        int length = 0;
                        byte[] buffer = new byte[1024];
                        // 发送光谱请求消息
                        SpectrumReq specReq = new SpectrumReq();
                        specReq.head.cmd1 = 0x01;
                        specReq.head.cmd2 = (byte)OPM_CmdID.CMD_READ_SPECTRUM;
                        specReq.chID = channel.no - 1;
                        specReq.sampleQuantity = sampleQuantity;
                        length = OPM_Protocol.MakeSpectrumReqPackage(ref buffer, specReq);
                        int rn = opm_Connector.SendToServer(buffer, 0, length);
                        if (rn != length)
                        {
                            return -1;
                        }

                        if (!isWaveStart)
                        {
                            QueueData data = null;
                            for (int i = 0; i < ssResp.frameNum; i++)
                            {
                                // 接收和解析设备信息应答消息
                                byte[] respBuffer = new byte[1024];
                                int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                                if (msgLen < 0)
                                {
                                    return -1;
                                }
                                OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                                if (cmd_id != OPM_CmdID.CMD_READ_SPECTRUM)
                                {
                                    return -1;
                                }

                                int pkgNo = respBuffer[3]; // 第几帧
                                if (pkgNo == ssResp.frameNum - 1)
                                {
                                    break;
                                }
                                SpectrumZData spData = new SpectrumZData();
                                int DataCountsPerPkg = (msgLen - 4) / 2;
                                int dataCounts = (ssResp.dataNum - pkgNo * DataCountsPerPkg) > DataCountsPerPkg ? DataCountsPerPkg : (ssResp.dataNum - pkgNo * DataCountsPerPkg);
                                if (-1 != OPM_Protocol.ParseSpectrumZDataPackage(respBuffer, dataCounts, ssResp, ref spData))
                                {
                                    spData.type = QueueDataType.DATA_SP;
                                    data = spData;
                                }

                                msgDispatcher.NotifyAll(data);
                            }
                        }
                    }
                }
            }
            return 0;
        }

        #endregion

        #region 通道参数
        public int ReadChParamter()
        {
            if(status != ConnectionStatus.CONNECTED)
            {
                return -1;
            }
            int rn = 0;
            lock (locker)
            {
                // 发送读取通道参数请求消息
                byte[] buffer = new byte[1024];
                ReadChannelParameterReq rcpReq = new ReadChannelParameterReq();
                ReadChannelParameterResp rcpResp = new ReadChannelParameterResp();
                rcpReq.head.cmd1 = 0x01;
                rcpReq.head.cmd2 = (byte)OPM_CmdID.CMD_READ_CHANNEL_PARAMETER;

                int length = OPM_Protocol.MakeReadChannelParameterReqPackage(ref buffer, rcpReq);

                rn = opm_Connector.SendToServer(buffer, 0, length);
                if (rn != length)
                {
                    return -1;
                }

                if (!isWaveStart)
                {
                    // 接收和解析设备信息应答消息
                    byte[] respBuffer = new byte[1024];
                    int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                    if (msgLen < 0)
                    {
                        return -1;
                    }
                    OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                    if (cmd_id != OPM_CmdID.CMD_READ_CHANNEL_PARAMETER)
                    {
                        return -1;
                    }
                    rn = OPM_Protocol.ParseReadChannelParameterRespPackage(respBuffer, ref rcpResp);
                    if (rn != 0)
                    {
                        return -1;
                    }

                    rcpResp.serialNo = serialNo;
                    TW_App.delegateCollection.SyncReadChParameter(rcpResp);
                }
            }
            return rn;
        }

        public int SetChannelParameter(ChannelParameter settingItem)
        {
            if (status != ConnectionStatus.CONNECTED)
            {
                logger.ErrorFormat("设置通道参数命令执行失败,因为设备还未连接成功, ip={0}, port={1}", ip, port);
                return -1;
            }

            lock (locker)
            {
                byte[] buffer = new byte[1024];
                WriteChannelParameterReq wcpReq = new WriteChannelParameterReq();
                wcpReq.head.cmd1 = 0x01;
                wcpReq.head.cmd2 = (byte)OPM_CmdID.CMD_SET_CHANNEL_PARAMETER;

                wcpReq.chID = settingItem.chID - 1;
                wcpReq.param = new ChannelParameter();
                wcpReq.param.threshold = settingItem.threshold;
                wcpReq.param.refThreshold = settingItem.refThreshold;
                wcpReq.param.width = settingItem.width;
                wcpReq.param.widthLevel = settingItem.widthLevel;
                wcpReq.param.isValley = settingItem.isValley;

                int length = OPM_Protocol.MakeWriteChannelParameterReqPackage(ref buffer, wcpReq);
                int rn = opm_Connector.SendToServer(buffer, 0, length);
                if (rn != length)
                {
                    return -1;
                }

                if (!isWaveStart)
                {
                    WriteChannelParameterResp wcpResp = new WriteChannelParameterResp();
                    // 接收和解析设备信息应答消息
                    byte[] respBuffer = new byte[1024];
                    int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                    if (msgLen < 0)
                    {
                        return -1;
                    }
                    OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                    if (cmd_id != OPM_CmdID.CMD_SET_CHANNEL_PARAMETER)
                    {
                        return -1;
                    }
                    rn = OPM_Protocol.ParseWriteChannelParameterRespPackage(respBuffer, ref wcpResp);
                    if (rn != 0)
                    {
                        return -1;
                    }

                    TW_App.delegateCollection.SyncSettingChParameter();
                }
            }

            return 0;
        }


        #endregion

        #region 读取设备频率
        public int ReadCurrentFrequency()
        {
            int result = -1;
            lock (locker)
            {
                // 读取频率
                byte[] buffer = new byte[1024];
                ReadDevFrequencyReq acqFrequencyReq = new ReadDevFrequencyReq();
                acqFrequencyReq.head.cmd1 = 0x01;
                acqFrequencyReq.head.cmd2 = (byte)OPM_CmdID.CMD_READ_MONITOR_FREQ;
                int length = OPM_Protocol.MakeReadDevFrequencyReqPackage(ref buffer, acqFrequencyReq);
                int rn = opm_Connector.SendToServer(buffer, 0, length);
                if (rn != length)
                {
                    return -1;
                }

                // 接收和解析频率应答消息
                byte[] respBuffer = new byte[1024];
                int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                if (msgLen < 0)
                {
                    return -1;
                }
                OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                if (cmd_id != OPM_CmdID.CMD_READ_MONITOR_FREQ)
                {
                    return -1;
                }
                ReadDevFrequencyResp afResp = new ReadDevFrequencyResp();
                rn = OPM_Protocol.ParseDevFrequencyRespPackage(respBuffer, ref afResp);
                if (rn != 0)
                {
                    return -1;
                }
                result = afResp.frequency;
            }

            return result;
        }
        #endregion


        #region 读取设备参数
        public ReadDeviceBaseInfoResp GetDeviceParameter()
        {
            if (status != ConnectionStatus.CONNECTED)
            {
                logger.ErrorFormat("读取设备参数命令执行失败,因为设备还未连接成功, ip={0}, port={1}", ip, port);
                return null;
            }

            lock (locker)
            {
                byte[] buffer = new byte[1024];
                byte[] respBuffer = new byte[4096];
                int rn;


                // 读取设备参数
                ReadDeviceBaseInfoReq deviceBaseInfoReq = new ReadDeviceBaseInfoReq();
                deviceBaseInfoReq.head.cmd1 = 0x01;
                deviceBaseInfoReq.head.cmd2 = (byte)OPM_CmdID.CMD_READ_PARAMETER;
                int length = OPM_Protocol.MakeReadDeviceBaseInfoReqPackage(ref buffer, deviceBaseInfoReq);
                rn = opm_Connector.SendToServer(buffer, 0, length);
                if (rn != length)
                {
                    return null;
                }

                // 接收和解析设备信息应答消息
                int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                if (msgLen < 0)
                {
                    return null;
                }
                OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                if (cmd_id != OPM_CmdID.CMD_READ_PARAMETER)
                {
                    return null;
                }
                ReadDeviceBaseInfoResp dbiResp = new ReadDeviceBaseInfoResp();
                rn = OPM_Protocol.ParseReadDeviceBaseInfoRespPackage(respBuffer, ref dbiResp);
                if (rn != 0)
                {
                    return null;
                }
                return dbiResp;
            }
        }

        public int SetDeviceParameter(ReadDeviceBaseInfoResp resp)
        {
            if (status != ConnectionStatus.CONNECTED)
            {
                logger.ErrorFormat("设置网络参数命令执行失败,因为设备还未连接成功, ip={0}, port={1}", ip, port);
                return -1;
            }
            int rn = -1;
            lock (locker)
            {
                byte[] buffer = new byte[1024];
                resp.head.cmd2 = 0x04;
                int length = OPM_Protocol.MakeChangeIPReqPackage(ref buffer, resp);
                rn = opm_Connector.SendToServer(buffer, 0, length);
                if(rn != length)
                {
                    return -1;
                }

                // 接收和解析
                byte[] respBuffer = new byte[1024];
                int msgLen = opm_Connector.RecvMsg(ref respBuffer, 0);
                if(msgLen < 0)
                {
                    return -1;
                }
                OPM_CmdID cmd_id = OPM_Protocol.GetCmd(respBuffer, msgLen);
                if(cmd_id != OPM_CmdID.CMD_WRITE_LOCAL_ADDR)
                {
                    return -1;
                }

            }
            return rn;
        }
        #endregion
    }
}
